<?php

/**
 * File Upload Wrapper
 * @package Nina
 * @author John Main <john@thedaddy.org>
 */
 class Nina_File_Upload {
	protected $handler;
	protected $name;
	protected $extension;
	protected $has_file = false;

	/**
	 * Constructor
	 * @param string $id The file ID within the request
	 */
	public function __construct($id) {
		$reg = Nina_Registry::getInstance();
		$request = $reg->get("runtime.request");
		
		if($request->hasParameter($id, 'FILES'))
			$this->handler = $request->getParameter($id, 'FILES');
		
		$this->has_file = ($this->handler && $this->handler['tmp_name'] && $this->handler['size'] > 0);
		$this->extension = strtolower(pathinfo($this->handler['name'], PATHINFO_EXTENSION));
	}
	
	/**
	 * Check if we have an uploaded file
	 * @preturn boolean
	 */
	public function hasFile() {
		return $this->has_file;
	}
	
	/**
	 * Get the file extension
	 * @preturn string
	 */
	public function getExtension() {
		return $this->extension;
	}
	
	/**
	 * Set the file name
	 * @param string $name The file name
	 */
	public function setName($name) {
		if(strpos($name, '.') !== false)
			$name = preg_replace('/\..+$/', '.' . $this->extension, $name);
		else
			$name .= '.' . $this->extension;

		$this->name = $name;
	}
	
	/**
	 * Get the file name
	 * @return string
	 */
	public function getName() {
		if($this->name)
			return $this->name;
		else
			return basename($this->handler['name']);
	}
	
	/**
	 * Save the file to the given path
	 * @param string $path The path to save to
	 * @return boolean
	 */
	public function save($path) {
		if($this->hasFile()) {
			if($this->pathWritable($path)) {
				$success = @move_uploaded_file($this->handler['tmp_name'], $path . DIRECTORY_SEPARATOR . $this->getName());

				if($success)
					return true;
			}
		}
		
		$this->handler['error'] = 9;
		return false;
	}
	
	/**
	 * Save the file to the given path
	 * @param string $path The path to save to
	 * @return boolean
	 */
	public function extract($path) {
		if($this->hasFile()) {
			if($this->pathWritable($path)) {
				if($this->getExtension() == 'zip') {
					$zip = new ZipArchive;
					$res = $zip->open($this->handler['tmp_name']);
					if ($res === true) {
						$success = $zip->extractTo($path);
						$zip->close();
						
						if($success)
							return true;
						else {
							$this->handler['error'] = 10;
							return false;
						}
					}
				}
				else
					return $this->save($path);
			}
		}
		
		$this->handler['error'] = 9;
		return false;
	}
	
	/**
	 * Get any upload error description
	 * @return string
	 */
	public function error() {
		if($this->hasFile()) {
			if(isset($this->handler['error']) && $this->handler['error']) {
				switch($this->handler['error']) {
		
					case '1':
						return 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
					case '2':
						return 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
					case '3':
						return 'The uploaded file was only partially uploaded';
					case '4':
						return 'No file was uploaded';
					case '6':
						return 'Missing a temporary folder';
					case '7':
						return 'Failed to write file to disk';
					case '8':
						return 'File upload stopped by extension';
					case '9':
						return 'File upload folder was not writable';
					case '10':
						return 'Zip archive could not be extracted';
					case '999':
					default:
						return 'An error occurred';
				}
			}
		}
		else
			return 'Parameter not found';
	}
	
	/**
	 * Check if the path is writable
	 * @return boolean
	 */
	protected function pathWritable($path) {
		return (is_dir($path) || mkdir($path)) && is_writable($path);
	}
}